﻿/*
 * link_next_simple.hpp
 *
 *  Created on: 2020年2月23日
 *      Author: Dylan.Gao
 */

#ifndef _DM_LINK_NEXT_SIMPLE_HPP_
#define _DM_LINK_NEXT_SIMPLE_HPP_

#include <dm/link_base.hpp>

namespace dm{

/**
 * 简单的单向链表，指向下一个
 * 注意，使用时不允许出现环，否则出现死循环
 */
template<typename T>
class TCLinkNextSimple:public TCLinkBase<T>{
public:
	TCLinkNextSimple():TCLinkBase<T>(),m_next(NULL){
	};

	TCLinkNextSimple( T p ):TCLinkBase<T>(p),m_next(NULL){
	}

	/**
	 * 将析构本节点开始的链表
	 */
	virtual ~TCLinkNextSimple();

	/**
	 * 以本节点开始的链表节点数量
	 * @return
	 */
	unsigned int size()const;

	inline TCLinkNextSimple* next(){
		return m_next;
	}

	inline const TCLinkNextSimple* next()const{
		return m_next;
	}

	bool insert( const T& p );
	bool insert( TCLinkNextSimple* l );

	bool removeNext();
	bool removeNexts();

	TCLinkNextSimple* popNext();
	TCLinkNextSimple* popNexts();

	TCLinkNextSimple* pushBack( const T& p );
	TCLinkNextSimple* pushBack( TCLinkNextSimple* l );
	TCLinkNextSimple* pushHead( const T& p );
	TCLinkNextSimple* pushHead( TCLinkNextSimple* l );

	TCLinkNextSimple* reverse();

	TCLinkNextSimple* end();
	const TCLinkNextSimple* end()const;
private:
	TCLinkNextSimple<T>* m_next;
};

template<typename T>
TCLinkNextSimple<T>::~TCLinkNextSimple(){
	if( m_next )
		delete m_next;
}

template<typename T>
unsigned int TCLinkNextSimple<T>::size()const{
	unsigned int rt = 1;
	const TCLinkNextSimple* p = this;
	while( (p = p->m_next) )
		++rt;

	return rt;
}

template<typename T>
bool TCLinkNextSimple<T>::insert( const T& p ){
	TCLinkNextSimple* n = m_next;
	m_next = new TCLinkNextSimple(p);
	m_next->m_next = n;

	return true;
}

/**
 * 插入操作，不允许插入含有环结构
 * @param l
 */
template<typename T>
bool TCLinkNextSimple<T>::insert( TCLinkNextSimple<T>* l ){
	TCLinkNextSimple* e = l->end();
	if( e==NULL )
		return false;

	TCLinkNextSimple* n = m_next;
	m_next = l;
	e->m_next = n;

	return true;
}

template<typename T>
bool TCLinkNextSimple<T>::removeNext(){
	if( m_next ){
		TCLinkNextSimple* n = m_next;
		m_next = n->m_next;
		n->m_next = NULL;
		delete n;
		return true;
	}
	return false;
}

template<typename T>
bool TCLinkNextSimple<T>::removeNexts(){
	if( m_next ){
		delete m_next;
		m_next = NULL;
		return true;
	}
	return false;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::popNext(){
	if( m_next ){
		TCLinkNextSimple* n = m_next;
		m_next = n->m_next;
		n->m_next = NULL;
		return n;
	}

	return NULL;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::popNexts(){
	if( m_next ){
		TCLinkNextSimple* n = m_next;
		m_next = NULL;
		return n;
	}

	return NULL;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::pushBack( const T& p ){
	end()->m_next = new TCLinkNextSimple(p);
	return this;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::pushBack( TCLinkNextSimple* l ){
	end()->m_next = l;
	return this;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::pushHead( const T& p ){
	TCLinkNextSimple* h = new TCLinkNextSimple(p);
	h->m_next = this;
	return h;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::pushHead( TCLinkNextSimple* l ){
	return l->pushBack(this);
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::reverse(){
	TCLinkNextSimple* l = this;
	TCLinkNextSimple* p = l->m_next;
	l->m_next = NULL;
	while( p ){
		TCLinkNextSimple* n = p->m_next;
		p->m_next = l;
		l = p;
		p = n;
	}

	return l;
}

template<typename T>
TCLinkNextSimple<T>* TCLinkNextSimple<T>::end(){
	TCLinkNextSimple* l = this;
	while( l->m_next )
		l = l->m_next;

	return l;
}

template<typename T>
const TCLinkNextSimple<T>* TCLinkNextSimple<T>::end()const{
	TCLinkNextSimple* l = this;
	while( l->m_next )
		l = l->m_next;

	return l;
}

}

#endif /* INCLUDE_DM_LINK_NEXT_SIMPLE_HPP_ */
